{{% macro sshd_config_source() %}}
#	$OpenBSD: sshd_config,v 1.103 2018/04/09 20:41:22 tj Exp $

# This is the sshd server system-wide configuration file.  See
# sshd_config(5) for more information.

# This sshd was compiled with PATH=/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin

# The strategy used for options in the default sshd_config shipped with
# OpenSSH is to specify options with their default value where
# possible, but leave them commented.  Uncommented options override the
# default value.

# If you want to change the port on a SELinux system, you have to tell
# SELinux about this change.
# semanage port -a -t ssh_port_t -p tcp #PORTNUMBER
#
#Port 22
#AddressFamily any
#ListenAddress 0.0.0.0
#ListenAddress ::

HostKey /etc/ssh/ssh_host_rsa_key
HostKey /etc/ssh/ssh_host_ecdsa_key
HostKey /etc/ssh/ssh_host_ed25519_key

# Ciphers and keying
RekeyLimit {{.var_rekey_limit_size}} {{.var_rekey_limit_time}}

# System-wide Crypto policy:
# This system is following system-wide crypto policy. The changes to
# Ciphers, MACs, KexAlgoritms and GSSAPIKexAlgorithsm will not have any
# effect here. They will be overridden by command-line options passed on
# the server start up.
# To opt out, uncomment a line with redefinition of  CRYPTO_POLICY=
# variable in  /etc/sysconfig/sshd  to overwrite the policy.
# For more information, see manual page for update-crypto-policies(8).

# Logging
#SyslogFacility AUTH
SyslogFacility AUTHPRIV
#LogLevel INFO

# Authentication:

#LoginGraceTime {{.var_sshd_set_login_grace_time}}
PermitRootLogin no
StrictModes yes
#MaxAuthTries 6
#MaxSessions 10

PubkeyAuthentication yes

# The default is to check both .ssh/authorized_keys and .ssh/authorized_keys2
# but this is overridden so installations will only check .ssh/authorized_keys
AuthorizedKeysFile	.ssh/authorized_keys

#AuthorizedPrincipalsFile none

#AuthorizedKeysCommand none
#AuthorizedKeysCommandUser nobody

# For this to work you will also need host keys in /etc/ssh/ssh_known_hosts
HostbasedAuthentication no
# Change to yes if you don't trust ~/.ssh/known_hosts for
# HostbasedAuthentication
IgnoreUserKnownHosts yes
# Don't read the user's ~/.rhosts and ~/.shosts files
IgnoreRhosts yes

# To disable tunneled clear text passwords, change to no here!
#PasswordAuthentication yes
PermitEmptyPasswords no
PasswordAuthentication no

# Change to no to disable s/key passwords
#ChallengeResponseAuthentication yes
ChallengeResponseAuthentication no

# Kerberos options
KerberosAuthentication no
#KerberosOrLocalPasswd yes
#KerberosTicketCleanup yes
#KerberosGetAFSToken no
#KerberosUseKuserok yes

# GSSAPI options
GSSAPIAuthentication no
GSSAPICleanupCredentials no
#GSSAPIStrictAcceptorCheck yes
#GSSAPIKeyExchange no
#GSSAPIEnablek5users no

# Set this to 'yes' to enable PAM authentication, account processing,
# and session processing. If this is enabled, PAM authentication will
# be allowed through the ChallengeResponseAuthentication and
# PasswordAuthentication.  Depending on your PAM configuration,
# PAM authentication via ChallengeResponseAuthentication may bypass
# the setting of "PermitRootLogin without-password".
# If you just want the PAM account and session checks to run without
# PAM authentication, then enable this but set PasswordAuthentication
# and ChallengeResponseAuthentication to 'no'.
# WARNING: 'UsePAM no' is not supported in Fedora and may cause several
# problems.
UsePAM yes

#AllowAgentForwarding yes
#AllowTcpForwarding yes
#GatewayPorts no
X11Forwarding yes
#X11DisplayOffset 10
#X11UseLocalhost yes
#PermitTTY yes

# It is recommended to use pam_motd in /etc/pam.d/sshd instead of PrintMotd,
# as it is more configurable and versatile than the built-in version.
PrintMotd no

PrintLastLog yes
#TCPKeepAlive yes
PermitUserEnvironment no
Compression {{.var_sshd_disable_compression}}
ClientAliveInterval {{.sshd_idle_timeout_value}}
ClientAliveCountMax {{.var_sshd_set_keepalive}}
#UseDNS no
#PidFile /var/run/sshd.pid
#MaxStartups 10:30:100
#PermitTunnel no
#ChrootDirectory none
#VersionAddendum none

# no default banner path
Banner /etc/issue

# Accept locale-related environment variables
AcceptEnv LANG LC_CTYPE LC_NUMERIC LC_TIME LC_COLLATE LC_MONETARY LC_MESSAGES
AcceptEnv LC_PAPER LC_NAME LC_ADDRESS LC_TELEPHONE LC_MEASUREMENT
AcceptEnv LC_IDENTIFICATION LC_ALL LANGUAGE
AcceptEnv XMODIFIERS

# override default of no subsystems
Subsystem	sftp	/usr/libexec/openssh/sftp-server

# Example of overriding settings on a per-user basis
#Match User anoncvs
#	X11Forwarding no
#	AllowTcpForwarding no
#	PermitTTY no
#	ForceCommand cvs server

UsePrivilegeSeparation {{.var_sshd_priv_separation}}
{{%- endmacro -%}}


{{#
  Macro which generates Kubernetes remediation in MachineConfig format:
    - path (String): Path to the configuration file.
    - file_permissions_mode (String): File permissions to be applied to the file represented by path argument
    - source_content (String): The source of the content to be applied.
#}}
{{%- macro kubernetes_machine_config_file(path='', file_permissions_mode='', source='') -%}}
apiVersion: machineconfiguration.openshift.io/v1
kind: MachineConfig
spec:
  config:
    ignition:
      version: 3.1.0
    storage:
      files:
      - contents:
          source: data:,{{ {{{ url_encode(source) }}} }}
        mode: {{{ file_permissions_mode }}}
        path: {{{ path }}}
        overwrite: true
{{%- endmacro -%}}

{{#
  Macro which generates Kubernetes remediation in MachineConfig format with
  dependencies reflected:
    - path (String): Path to the configuration file.
    - file_permissions_mode (String): File permissions to be applied to the file represented by path argument
    - source_content (String): The source of the content to be applied.
    - deps (list): The list of dependencies for this remediation to be applies (they're XCCDF IDs)
    - ocp_version_deps (String): States that the remediation needs a certain OpenShift version range to work
    - k8s_version_deps (String): States that the remediation needs a certain Kubernetes version range to work
#}}
{{%- macro kubernetes_machine_config_file_with_dependencies(path='', file_permissions_mode='', source='', deps=[], ocp_version_range='', k8s_version_range='') -%}}
apiVersion: machineconfiguration.openshift.io/v1
kind: MachineConfig
metadata:
  annotations:
    complianceascode.io/depends-on: {{{ deps | join(",") }}}
{{%- if ocp_version_range|length > 0 %}}
    complianceascode.io/ocp-version: '{{{ ocp_version_range }}}'
{{%- endif %}}
{{%- if k8s_version_range|length > 0 %}}
    complianceascode.io/k8s-version: '{{{ k8s_version_range }}}'
{{%- endif %}}
spec:
  config:
    ignition:
      version: 3.1.0
    storage:
      files:
      - contents:
          source: data:,{{ {{{ url_encode(source) }}} }}
        mode: {{{ file_permissions_mode }}}
        path: {{{ path }}}
        overwrite: true
{{%- endmacro -%}}


{{#
  Macro which generates Kubernetes remediation in MachineConfig format with
  required value
    - path (String): Path to the configuration file.
    - file_permissions_mode (String): File permissions to be applied to the file represented by path argument
    - source_content (String): The source of the content to be applied.
    - vals (list): The list of required values for this remediation to be applies for example: var_something
#}}

{{%- macro kubernetes_machine_config_file_with_required_value(path='', file_permissions_mode='', source='', vals=[]) -%}}
apiVersion: machineconfiguration.openshift.io/v1
kind: MachineConfig
metadata:
  annotations:
    complianceascode.io/value-input-required: {{{ vals | join(",") }}}
spec:
  config:
    ignition:
      version: 3.1.0
    storage:
      files:
      - contents:
          source: data:,{{ {{{ url_encode(source) }}} }}
        mode: {{{ file_permissions_mode }}}
        path: {{{ path }}}
        overwrite: true
{{%- endmacro -%}}


{{#
  High level macro to generate Kubernetes remediation to set the ssh daemon configuration file.
#}}
{{%- macro kubernetes_sshd_set() -%}}
{{{ kubernetes_machine_config_file(path='/etc/ssh/sshd_config', file_permissions_mode='0600', source=sshd_config_source()) }}}
{{%- endmacro -%}}


{{% macro usbguard_config_source() %}}
#
# Rule set file path.
#
# The USBGuard daemon will use this file to load the policy
# rule set from it and to write new rules received via the
# IPC interface.
#
# RuleFile=/path/to/rules.conf
#
RuleFile=/etc/usbguard/rules.conf

#
# Rule set folder path.
#
# The USBGuard daemon will use this folder to load the policy
# rule set from it and to write new rules received via the
# IPC interface. Usually, we set the option to
# /etc/usbguard/rules.d/. The USBGuard daemon is supposed to
# behave like any other standard Linux daemon therefore it
# loads rule files in alpha-numeric order. File names inside
# RuleFolder directory should start with a two-digit number
# prefix indicating the position, in which the rules are
# scanned by the daemon.
#
# RuleFolder=/path/to/rulesfolder/
#
RuleFolder=/etc/usbguard/rules.d/

#
# Implicit policy target.
#
# How to treat devices that don't match any rule in the
# policy. One of:
#
# * allow  - authorize the device
# * block  - block the device
# * reject - remove the device
#
ImplicitPolicyTarget=block

#
# Present device policy.
#
# How to treat devices that are already connected when the
# daemon starts. One of:
#
# * allow        - authorize every present device
# * block        - deauthorize every present device
# * reject       - remove every present device
# * keep         - just sync the internal state and leave it
# * apply-policy - evaluate the ruleset for every present
#                  device
#
PresentDevicePolicy=apply-policy

#
# Present controller policy.
#
# How to treat USB controllers that are already connected
# when the daemon starts. One of:
#
# * allow        - authorize every present device
# * block        - deauthorize every present device
# * reject       - remove every present device
# * keep         - just sync the internal state and leave it
# * apply-policy - evaluate the ruleset for every present
#                  device
#
PresentControllerPolicy=keep

#
# Inserted device policy.
#
# How to treat USB devices that are already connected
# *after* the daemon starts. One of:
#
# * block        - deauthorize every present device
# * reject       - remove every present device
# * apply-policy - evaluate the ruleset for every present
#                  device
#
InsertedDevicePolicy=apply-policy

#
# Control which devices are authorized by default.
#
# The USBGuard daemon modifies some the default authorization state attributes
# of controller devices. This setting, enables you to define what value the
# default authorization is set to.
#
# * keep         - do not change the authorization state
# * none         - every new device starts out deauthorized
# * all          - every new device starts out authorized
# * internal     - internal devices start out authorized, external devices start
#                  out deauthorized (this requires the ACPI tables to properly
#                  label internal devices, and kernel support)
#
#AuthorizedDefault=none

#
# Restore controller device state.
#
# The USBGuard daemon modifies some attributes of controller
# devices like the default authorization state of new child device
# instances. Using this setting, you can control whether the
# daemon will try to restore the attribute values to the state
# before modification on shutdown.
#
# SECURITY CONSIDERATIONS: If set to true, the USB authorization
# policy could be bypassed by performing some sort of attack on the
# daemon (via a local exploit or via a USB device) to make it shutdown
# and restore to the operating-system default state (known to be permissive).
#
RestoreControllerDeviceState=false

#
# Device manager backend
#
# Which device manager backend implementation to use. One of:
#
# * uevent   - Netlink based implementation which uses sysfs to scan for present
#              devices and an uevent netlink socket for receiving USB device
#              related events.
# * umockdev - umockdev based device manager capable of simulating devices based
#              on umockdev-record files. Useful for testing.
#
DeviceManagerBackend=uevent

#!!! WARNING: It's good practice to set at least one of the !!!
#!!!          two options bellow. If none of them are set,  !!!
#!!!          the daemon will accept IPC connections from   !!!
#!!!          anyone, thus allowing anyone to modify the    !!!
#!!!          rule set and (de)authorize USB devices.       !!!

#
# Users allowed to use the IPC interface.
#
# A space delimited list of usernames that the daemon will
# accept IPC connections from.
#
# IPCAllowedUsers=username1 username2 ...
#
IPCAllowedUsers=root

#
# Groups allowed to use the IPC interface.
#
# A space delimited list of groupnames that the daemon will
# accept IPC connections from.
#
# IPCAllowedGroups=groupname1 groupname2 ...
#
IPCAllowedGroups=wheel

#
# IPC access control definition files path.
#
# The files at this location will be interpreted by the daemon
# as access control definition files. The (base)name of a file
# should be in the form:
#
#   [user][:<group>]
#
# and should contain lines in the form:
#
#   <section>=[privilege] ...
#
# This way each file defines who is able to connect to the IPC
# bus and what privileges he has.
#
IPCAccessControlFiles=/etc/usbguard/IPCAccessControl.d/

#
# Generate device specific rules including the "via-port"
# attribute.
#
# This option modifies the behavior of the allowDevice
# action. When instructed to generate a permanent rule,
# the action can generate a port specific rule. Because
# some systems have unstable port numbering, the generated
# rule might not match the device after rebooting the system.
#
# If set to false, the generated rule will still contain
# the "parent-hash" attribute which also defines an association
# to the parent device. See usbguard-rules.conf(5) for more
# details.
#
DeviceRulesWithPort=false

#
# USBGuard Audit events log backend
#
# One of:
#
# * FileAudit - Log audit events into a file specified by
#               AuditFilePath setting (see below)
# * LinuxAudit - Log audit events using the Linux Audit
#                subsystem (using audit_log_user_message)
#
AuditBackend=LinuxAudit

#
# USBGuard audit events log file path.
#
#AuditFilePath=/var/log/usbguard/usbguard-audit.log

#
# Hides personally identifiable information such as device serial numbers and
# hashes of descriptors (which include the serial number) from audit entries.
#
#HidePII=false
{{%- endmacro -%}}


{{#
  High level macro to generate Kubernetes remediation to set the usbguard daemon configuration file.
#}}
{{%- macro kubernetes_usbguard_set(deps=[]) -%}}
{{{ kubernetes_machine_config_file_with_dependencies(path='/etc/usbguard/usbguard-daemon.conf', file_permissions_mode='0600', source=usbguard_config_source(), deps=deps, ocp_version_range='>=4.7.0') }}}
{{%- endmacro -%}}

{{% macro kubernetes_machineconfig_audit_add_watch_rule(path='', permissions='', key='') -%}}
{{%- set audit_watch_rule = "-w " + path + " -p " + permissions + " -k " + key + "\n" -%}}
{{%- set audit_watch_rule_path = "/etc/audit/rules.d/75-" + path | replace('/', '')  + "-" + permissions + "-" + key + ".rules" -%}}
{{{ kubernetes_machine_config_file(path=audit_watch_rule_path, file_permissions_mode='0600', source=audit_watch_rule) }}}
{{%- endmacro %}}

{{% macro audit_syscalls_rule(syscalls=[], key='', fields='') %}}
{{%- for syscall in syscalls -%}}
-a always,exit -F arch=b64 -S {{{ syscall }}}{{% if fields %}} -F {{{ fields }}}{{% endif %}} -k {{{ key }}}
-a always,exit -F arch=b32 -S {{{ syscall }}}{{% if fields %}} -F {{{ fields }}}{{% endif %}} -k {{{ key }}}
{{% endfor %}}
{{%- endmacro %}}


{{#
  Macro to generate MachineConfig adding an auditd rule for syscall watching
#}}
{{% macro kubernetes_machineconfig_audit_add_syscall_rule(path='', syscalls=[], key='', fields='') -%}}
{{{ kubernetes_machine_config_file(path=path, file_permissions_mode='0600', source=audit_syscalls_rule(syscalls, key, fields)) }}}
{{%- endmacro %}}

{{% macro rhcos_ospp_audit_rules() -%}}
## This content is a section of an Audit config snapshot recommended for {{{full_name|urlencode}}} systems that target OSPP compliance.
## The following content has been retreived on 2019-03-11 from: https://github.com/linux-audit/audit-userspace/blob/master/rules/30-ospp-v42.rules

## The purpose of these rules is to meet the requirements for Operating
## System Protection Profile (OSPP)v4.2. These rules depends on having
## 10-base-config.rules, 11-loginuid.rules, and 43-module-load.rules installed.

## Unsuccessful file creation (open with O_CREAT)
-a always,exit -F arch=b32 -S openat,open_by_handle_at -F a2&0100 -F exit=-EACCES -F auid>=1000 -F auid!=unset -F key=unsuccesful-create
-a always,exit -F arch=b64 -S openat,open_by_handle_at -F a2&0100 -F exit=-EACCES -F auid>=1000 -F auid!=unset -F key=unsuccesful-create
-a always,exit -F arch=b32 -S open -F a1&0100 -F exit=-EACCES -F auid>=1000 -F auid!=unset -F key=unsuccesful-create
-a always,exit -F arch=b64 -S open -F a1&0100 -F exit=-EACCES -F auid>=1000 -F auid!=unset -F key=unsuccesful-create
-a always,exit -F arch=b32 -S openat,open_by_handle_at -F a2&0100 -F exit=-EPERM -F auid>=1000 -F auid!=unset -F key=unsuccesful-create
-a always,exit -F arch=b64 -S openat,open_by_handle_at -F a2&0100 -F exit=-EPERM -F auid>=1000 -F auid!=unset -F key=unsuccesful-create
-a always,exit -F arch=b32 -S open -F a1&0100 -F exit=-EPERM -F auid>=1000 -F auid!=unset -F key=unsuccesful-create
-a always,exit -F arch=b64 -S open -F a1&0100 -F exit=-EPERM -F auid>=1000 -F auid!=unset -F key=unsuccesful-create
-a always,exit -F arch=b32 -S creat -F exit=-EACCES -F auid>=1000 -F auid!=unset -F key=unsuccesful-create
-a always,exit -F arch=b64 -S creat -F exit=-EACCES -F auid>=1000 -F auid!=unset -F key=unsuccesful-create
-a always,exit -F arch=b32 -S creat -F exit=-EPERM -F auid>=1000 -F auid!=unset -F key=unsuccesful-create
-a always,exit -F arch=b64 -S creat -F exit=-EPERM -F auid>=1000 -F auid!=unset -F key=unsuccesful-create

## Unsuccessful file modifications (open for write or truncate)
-a always,exit -F arch=b32 -S openat,open_by_handle_at -F a2&01003 -F exit=-EACCES -F auid>=1000 -F auid!=unset -F key=unsuccesful-modification
-a always,exit -F arch=b64 -S openat,open_by_handle_at -F a2&01003 -F exit=-EACCES -F auid>=1000 -F auid!=unset -F key=unsuccesful-modification
-a always,exit -F arch=b32 -S open -F a1&01003 -F exit=-EACCES -F auid>=1000 -F auid!=unset -F key=unsuccesful-modification
-a always,exit -F arch=b64 -S open -F a1&01003 -F exit=-EACCES -F auid>=1000 -F auid!=unset -F key=unsuccesful-modification
-a always,exit -F arch=b32 -S openat,open_by_handle_at -F a2&01003 -F exit=-EPERM -F auid>=1000 -F auid!=unset -F key=unsuccesful-modification
-a always,exit -F arch=b64 -S openat,open_by_handle_at -F a2&01003 -F exit=-EPERM -F auid>=1000 -F auid!=unset -F key=unsuccesful-modification
-a always,exit -F arch=b32 -S open -F a1&01003 -F exit=-EPERM -F auid>=1000 -F auid!=unset -F key=unsuccesful-modification
-a always,exit -F arch=b64 -S open -F a1&01003 -F exit=-EPERM -F auid>=1000 -F auid!=unset -F key=unsuccesful-modification
-a always,exit -F arch=b32 -S truncate,ftruncate -F exit=-EACCES -F auid>=1000 -F auid!=unset -F key=unsuccesful-modification
-a always,exit -F arch=b64 -S truncate,ftruncate -F exit=-EACCES -F auid>=1000 -F auid!=unset -F key=unsuccesful-modification
-a always,exit -F arch=b32 -S truncate,ftruncate -F exit=-EPERM -F auid>=1000 -F auid!=unset -F key=unsuccesful-modification
-a always,exit -F arch=b64 -S truncate,ftruncate -F exit=-EPERM -F auid>=1000 -F auid!=unset -F key=unsuccesful-modification

## Unsuccessful file access (any other opens) This has to go last.
-a always,exit -F arch=b32 -S open,creat,truncate,ftruncate,openat,open_by_handle_at -F exit=-EACCES -F auid>=1000 -F auid!=unset -F key=unsuccesful-access
-a always,exit -F arch=b64 -S open,creat,truncate,ftruncate,openat,open_by_handle_at -F exit=-EACCES -F auid>=1000 -F auid!=unset -F key=unsuccesful-access
-a always,exit -F arch=b32 -S open,creat,truncate,ftruncate,openat,open_by_handle_at -F exit=-EPERM -F auid>=1000 -F auid!=unset -F key=unsuccesful-access
-a always,exit -F arch=b64 -S open,creat,truncate,ftruncate,openat,open_by_handle_at -F exit=-EPERM -F auid>=1000 -F auid!=unset -F key=unsuccesful-access
{{%- endmacro %}}


{{#
  Macro to generate MachineConfig setting OSPP audit rules
#}}
{{% macro kubernetes_machineconfig_ospp_audit_rules() -%}}
{{{ kubernetes_machine_config_file(path='/etc/audit/rules.d/30-ospp-v42-remediation.rules', file_permissions_mode='0600', source=rhcos_ospp_audit_rules()) }}}
{{%- endmacro %}}

{{% macro rhcos_logrotate_config() -%}}
# see "man logrotate" for details
# rotate log files daily
daily

# keep 4 weeks worth of backlogs
rotate 30

# create new (empty) log files after rotating old ones
create

# use date as a suffix of the rotated file
dateext

# uncomment this if you want your log files compressed
#compress

# RPM packages drop log rotation information into this directory
include /etc/logrotate.d

# system-specific logs may be also be configured here.
{{%- endmacro %}}


{{#
  Macro to generate MachineConfig setting our recommended logrotate.conf
#}}
{{% macro kubernetes_machineconfig_logrotate_config() -%}}
{{{ kubernetes_machine_config_file(path='/etc/logrotate.conf', file_permissions_mode='0644', source=rhcos_logrotate_config()) }}}
{{%- endmacro %}}

{{% macro rhcos_auditd_config() -%}}
#
# This file controls the configuration of the audit daemon
#

local_events = yes
write_logs = yes
log_file = /var/log/audit/audit.log
log_group = root
log_format = ENRICHED
flush = {{.var_auditd_flush}}
freq = 50
max_log_file = {{.var_auditd_max_log_file}}
num_logs = {{.var_auditd_num_logs}}
priority_boost = 4
name_format = hostname
##name = mydomain
max_log_file_action = {{.var_auditd_max_log_file_action}}
space_left = {{.var_auditd_space_left}}
space_left_action = {{.var_auditd_space_left_action}}
verify_email = yes
action_mail_acct = {{.var_auditd_action_mail_acct}}
admin_space_left = 50
admin_space_left_action = syslog
disk_full_action = {{.var_auditd_disk_full_action}}
disk_error_action = {{.var_auditd_disk_error_action}}
use_libwrap = yes
##tcp_listen_port = 60
tcp_listen_queue = 5
tcp_max_per_addr = 1
##tcp_client_ports = 1024-65535
tcp_client_max_idle = 0
transport = TCP
krb5_principal = auditd
##krb5_key_file = /etc/audit/audit.key
distribute_network = no
q_depth = 400
overflow_action = syslog
max_restarts = 10
plugin_dir = /etc/audit/plugins.d
{{%- endmacro %}}


{{#
  Macro to generate MachineConfig setting our recommended auditd.conf
#}}
{{% macro kubernetes_machineconfig_auditd_config() -%}}
{{{ kubernetes_machine_config_file(path='/etc/audit/auditd.conf', file_permissions_mode='0640', source=rhcos_auditd_config()) }}}
{{%- endmacro %}}

{{% macro kubernetes_machineconfig_auditd_config_with_required_value(vals=[]) -%}}
{{{ kubernetes_machine_config_file_with_required_value(path='/etc/audit/auditd.conf', file_permissions_mode='0640', source=rhcos_auditd_config(),vals=vals)}}}
{{%- endmacro %}}


{{#
  Macro to generate MachineConfig setting our recommended chrony.conf
#}}
{{% macro kubernetes_machineconfig_chrony_config() -%}}
apiVersion: machineconfiguration.openshift.io/v1
kind: MachineConfig
spec:
  config:
    ignition:
      version: 3.1.0
    storage:
      files:
      - contents:
          source: data:,{{ %23%20Allow%20for%20extra%20configuration%20files.%20This%20is%20useful%0A%23%20for%20admins%20specifying%20their%20own%20NTP%20servers%0Ainclude%20/etc/chrony.d/%2A.conf%0A%0A%23%20Set%20chronyd%20as%20client-only.%0Aport%200%0A%0A%23%20Disable%20chronyc%20from%20the%20network%0Acmdport%200%0A%0A%23%20Record%20the%20rate%20at%20which%20the%20system%20clock%20gains/losses%20time.%0Adriftfile%20/var/lib/chrony/drift%0A%0A%23%20Allow%20the%20system%20clock%20to%20be%20stepped%20in%20the%20first%20three%20updates%0A%23%20if%20its%20offset%20is%20larger%20than%201%20second.%0Amakestep%201.0%203%0A%0A%23%20Enable%20kernel%20synchronization%20of%20the%20real-time%20clock%20%28RTC%29.%0Artcsync%0A%0A%23%20Enable%20hardware%20timestamping%20on%20all%20interfaces%20that%20support%20it.%0A%23hwtimestamp%20%2A%0A%0A%23%20Increase%20the%20minimum%20number%20of%20selectable%20sources%20required%20to%20adjust%0A%23%20the%20system%20clock.%0A%23minsources%202%0A%0A%23%20Allow%20NTP%20client%20access%20from%20local%20network.%0A%23allow%20192.168.0.0/16%0A%0A%23%20Serve%20time%20even%20if%20not%20synchronized%20to%20a%20time%20source.%0A%23local%20stratum%2010%0A%0A%23%20Require%20authentication%20%28nts%20or%20key%20option%29%20for%20all%20NTP%20sources.%0A%23authselectmode%20require%0A%0A%23%20Specify%20file%20containing%20keys%20for%20NTP%20authentication.%0Akeyfile%20/etc/chrony.keys%0A%0A%23%20Insert/delete%20leap%20seconds%20by%20slewing%20instead%20of%20stepping.%0A%23leapsecmode%20slew%0A%0A%23%20Get%20TAI-UTC%20offset%20and%20leap%20seconds%20from%20the%20system%20tz%20database.%0Aleapsectz%20right/UTC%0A%0A%23%20Specify%20directory%20for%20log%20files.%0Alogdir%20/var/log/chrony%0A%0A%23%20Select%20which%20information%20is%20logged.%0A%23log%20measurements%20statistics%20tracking }}
        mode: 420
        overwrite: true
        path: /etc/chrony.conf
      - contents:
          source: data:,
        mode: 420
        overwrite: true
        path: /etc/chrony.d/.mco-keep
      - contents:
          source: data:,{{ {{{ url_encode(ntp_server()) }}} }}
        mode: 420
        overwrite: true
        path: /etc/chrony.d/ntp-server.conf
{{%- endmacro %}}

{{% macro ntp_server() -%}}
#
# This file controls the configuration of the ntp server
# {{.var_multiple_time_servers}} we have to put variable array name here for mutilines remediation 
{{$var_time_service_set_maxpoll:=.var_time_service_set_maxpoll}}
{{range $element:=.var_multiple_time_servers|toArrayByComma}}server {{$element}} minpoll 4 maxpoll {{$var_time_service_set_maxpoll}}
{{end}}
{{%- endmacro %}}


{{#
  Macro which generates Kubernetes remediation in APIServer format:
    - path (String): path for the variable
    - parameter (String): name of the variable to be set
    - value (String): xccdf vairable name to that varaiable
#}}
{{%- macro api_server_config(path='',parameter='', value='') -%}}
apiVersion: config.openshift.io/v1
kind: APIServer
metadata:
  name: cluster
spec:
{{{ expand_yaml_path(path, parameter) }}}: {{.{{{ value }}}}}
{{%- endmacro -%}}

{{#
   Macro which generates Kubernetes remediation in kubelet config format:
     - path (String): path for the variable
     - parameter (String): name of the variable to be set
     - value (String): xccdf vairable name to that varaiable
#}}
{{%- macro kubelet_config(path='', parameter='', value='', role='') -%}}
apiVersion: machineconfiguration.openshift.io/v1
kind: KubeletConfig
metadata:
  annotations:
    complianceascode.io/node-role: "{{.{{{ role }}}}}"
spec:
{{{ expand_yaml_path(path, parameter) }}}: {{.{{{ value }}}}}
{{%- endmacro -%}} 

{{#
   Macro which generates Kubernetes remediation in kubelet config format:
     - path (String): path for the variable
     - parameter (String): name of the variable to be set
     - value (String): the fixed value to that varaiable
#}}
{{%- macro kubelet_config_fixed(path='', parameter='', value='', role='') -%}}
apiVersion: machineconfiguration.openshift.io/v1
kind: KubeletConfig
metadata:
  annotations:
    complianceascode.io/node-role: "{{.{{{ role }}}}}"
spec:
{{{ expand_yaml_path(path, parameter) }}}: {{{ value }}}
{{%- endmacro -%}}

